\subsubsection{ARM + \OptimizingKeilVI (\ARMMode)}

\begin{lstlisting}[caption=\OptimizingKeilVI (\ARMMode),style=customasmARM]
02 0C C0 E3          BIC     R0, R0, #0x200
01 09 80 E3          ORR     R0, R0, #0x4000
1E FF 2F E1          BX      LR
\end{lstlisting}

\myindex{ARM!\Instructions!BIC}
\INS{BIC} (\IT{BItwise bit Clear}) is an instruction for clearing 
specific bits. This is just like the \AND instruction, but with inverted operand.
I.e., it's analogous to a \NOT+\AND instruction pair.

\myindex{ARM!\Instructions!ORR}
\INS{ORR} is \q{logical or}, analogous to \OR in x86.

So far it's easy.

\subsubsection{ARM + \OptimizingKeilVI (\ThumbMode)}

\begin{lstlisting}[caption=\OptimizingKeilVI (\ThumbMode),style=customasmARM]
01 21 89 03          MOVS    R1, 0x4000
08 43                ORRS    R0, R1
49 11                ASRS    R1, R1, #5   ; generate 0x200 and place to R1
88 43                BICS    R0, R1
70 47                BX      LR
\end{lstlisting}

Seems like Keil decided that the code in Thumb mode,
making \TT{0x200} from \TT{0x4000}, 
is more compact than the code 
for writing \TT{0x200} to an arbitrary register.
% TODO1 пример, как компилятор при помощи сдвигов оптизирует такое: a=0x1000; b=0x2000; c=0x4000, etc

\myindex{ARM!\Instructions!ASRS}

So that is why, with the help of \INS{ASRS} (\ASRdesc), this value is calculated as $\TT{0x4000} \gg 5$.

\subsubsection{ARM + \OptimizingXcodeIV (\ARMMode)}
\label{anomaly:LLVM}
\myindex{\CompilerAnomaly}

\begin{lstlisting}[caption=\OptimizingXcodeIV (\ARMMode),label=ARM_leaf_example3,style=customasmARM]
42 0C C0 E3          BIC             R0, R0, #0x4200
01 09 80 E3          ORR             R0, R0, #0x4000
1E FF 2F E1          BX              LR
\end{lstlisting}

The code that was generated by LLVM, in source code form could be something like this:

\begin{lstlisting}[style=customc]
    REMOVE_BIT (rt, 0x4200);
    SET_BIT (rt, 0x4000);
\end{lstlisting}

And it does exactly what we need. 
But why \TT{0x4200}? 
Perhaps that an artifact from LLVM's optimizer
\footnote{It was LLVM build 2410.2.00 bundled with Apple Xcode 4.6.3}.

Probably a compiler's optimizer error, but the generated code works correctly anyway.

You can read more about compiler anomalies here~(\myref{anomaly:Intel}).

\OptimizingXcodeIV for Thumb mode generates the same code.

\subsubsection{ARM: more about the \INS{BIC} instruction}
\myindex{ARM!\Instructions!BIC}

Let's rework the example slightly:

\begin{lstlisting}[style=customc]
int f(int a)
{
    int rt=a;

    REMOVE_BIT (rt, 0x1234);

    return rt;
};
\end{lstlisting}

Then the optimizing Keil 5.03 
in ARM mode does:

\begin{lstlisting}[style=customasmARM]
f PROC
        BIC      r0,r0,#0x1000
        BIC      r0,r0,#0x234
        BX       lr
        ENDP
\end{lstlisting}

There are two \INS{BIC} instructions, i.e., bits \TT{0x1234} are cleared in two passes.

This is because it's not possible to encode \TT{0x1234} in a \INS{BIC} instruction, 
but it's possible to encode \TT{0x1000} and \TT{0x234}.

\subsubsection{ARM64: \Optimizing GCC (Linaro) 4.9}

\Optimizing GCCcompiling for ARM64 can use the \AND instruction instead of \INS{BIC}:

\begin{lstlisting}[caption=\Optimizing GCC (Linaro) 4.9,style=customasmARM]
f:
	and	w0, w0, -513	; 0xFFFFFFFFFFFFFDFF
	orr	w0, w0, 16384	; 0x4000
	ret
\end{lstlisting}

\subsubsection{ARM64: \NonOptimizing GCC (Linaro) 4.9}

\NonOptimizing GCC generates more redundant code, but works just like optimized:

\begin{lstlisting}[caption=\NonOptimizing GCC (Linaro) 4.9,style=customasmARM]
f:
	sub	sp, sp, #32
	str	w0, [sp,12]
	ldr	w0, [sp,12]
	str	w0, [sp,28]
	ldr	w0, [sp,28]
	orr	w0, w0, 16384	; 0x4000
	str	w0, [sp,28]
	ldr	w0, [sp,28]
	and	w0, w0, -513	; 0xFFFFFFFFFFFFFDFF
	str	w0, [sp,28]
	ldr	w0, [sp,28]
	add	sp, sp, 32
	ret
\end{lstlisting}
